﻿// Decompiled with JetBrains decompiler
// Type: System.Web.Razor.Tokenizer.HtmlTokenizer
// Assembly: System.Web.Razor, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35
// MVID: 682513D6-F37E-48AC-9909-F3EE103CFF14
// Assembly location: D:\Project\Idea\无人机外网\uav\客户端工程\排查工具\bin\Release\System.Web.Razor.dll

using System.Collections.Generic;
using System.Web.Razor.Parser;
using System.Web.Razor.Parser.SyntaxTree;
using System.Web.Razor.Text;
using System.Web.Razor.Tokenizer.Symbols;

namespace System.Web.Razor.Tokenizer
{
  /// <summary>This type/member supports the .NET Framework infrastructure and is not intended to be used directly from your code.Represents the html tokenizer of the razor.</summary>
  public class HtmlTokenizer : System.Web.Razor.Tokenizer.Tokenizer<HtmlSymbol, HtmlSymbolType>
  {
    private const char TransitionChar = '@';

    /// <summary>This type/member supports the .NET Framework infrastructure and is not intended to be used directly from your code.Initializes a new instance of the <see cref="T:System.Web.Razor.Tokenizer.HtmlTokenizer" /> class.</summary>
    /// <param name="source">The source for the text document.</param>
    public HtmlTokenizer(ITextDocument source)
      : base(source)
    {
      this.CurrentState = new StateMachine<HtmlSymbol>.State(this.Data);
    }

    /// <summary>This type/member supports the .NET Framework infrastructure and is not intended to be used directly from your code.Gets the start of the state machine for the html.</summary>
    /// <returns>The start of the state machine for the html.</returns>
    protected override StateMachine<HtmlSymbol>.State StartState => new StateMachine<HtmlSymbol>.State(this.Data);

    /// <summary>This type/member supports the .NET Framework infrastructure and is not intended to be used directly from your code.Gets the html symbols for the razor comment type.</summary>
    /// <returns>The html symbols for the razor comment type.</returns>
    public override HtmlSymbolType RazorCommentType => HtmlSymbolType.RazorComment;

    /// <summary>This type/member supports the .NET Framework infrastructure and is not intended to be used directly from your code.Gets the html symbols for the razor comment transition type.</summary>
    /// <returns>The html symbols for the razor comment transition type.</returns>
    public override HtmlSymbolType RazorCommentTransitionType => HtmlSymbolType.RazorCommentTransition;

    /// <summary>This type/member supports the .NET Framework infrastructure and is not intended to be used directly from your code.Gets the html symbols for the razor comment star type.</summary>
    /// <returns>The html symbols for the razor comment star type.</returns>
    public override HtmlSymbolType RazorCommentStarType => HtmlSymbolType.RazorCommentStar;

    internal static IEnumerable<HtmlSymbol> Tokenize(string content)
    {
      using (SeekableTextReader reader = new SeekableTextReader(content))
      {
        HtmlTokenizer tok = new HtmlTokenizer((ITextDocument) reader);
        HtmlSymbol htmlSymbol;
        while ((htmlSymbol = tok.NextSymbol()) != null)
          yield return htmlSymbol;
        tok = (HtmlTokenizer) null;
      }
    }

    /// <summary>This type/member supports the .NET Framework infrastructure and is not intended to be used directly from your code.Creates a symbol for the specified parameters of the html tokenizer.</summary>
    /// <returns>A symbol to create for the specified parameters of the html tokenizer.</returns>
    /// <param name="start">The source location.</param>
    /// <param name="content">The content string.</param>
    /// <param name="type">The type of html symbol.</param>
    /// <param name="errors">The razor errors.</param>
    protected override HtmlSymbol CreateSymbol(
      SourceLocation start,
      string content,
      HtmlSymbolType type,
      IEnumerable<RazorError> errors)
    {
      return new HtmlSymbol(start, content, type, errors);
    }

    private StateMachine<HtmlSymbol>.StateResult Data()
    {
      if (ParserHelpers.IsWhitespace(this.CurrentCharacter))
        return this.Stay(this.Whitespace());
      if (ParserHelpers.IsNewLine(this.CurrentCharacter))
        return this.Stay(this.Newline());
      if (this.CurrentCharacter == '@')
      {
        this.TakeCurrent();
        if (this.CurrentCharacter == '*')
          return this.Transition(this.EndSymbol(HtmlSymbolType.RazorCommentTransition), new StateMachine<HtmlSymbol>.State(((System.Web.Razor.Tokenizer.Tokenizer<HtmlSymbol, HtmlSymbolType>) this).AfterRazorCommentTransition));
        return this.CurrentCharacter == '@' ? this.Transition(this.EndSymbol(HtmlSymbolType.Transition), (StateMachine<HtmlSymbol>.State) (() =>
        {
          this.TakeCurrent();
          return this.Transition(this.EndSymbol(HtmlSymbolType.Transition), new StateMachine<HtmlSymbol>.State(this.Data));
        })) : this.Stay(this.EndSymbol(HtmlSymbolType.Transition));
      }
      return this.AtSymbol() ? this.Stay(this.Symbol()) : this.Transition(new StateMachine<HtmlSymbol>.State(this.Text));
    }

    private StateMachine<HtmlSymbol>.StateResult Text()
    {
      char ch1 = char.MinValue;
      while (!this.EndOfFile && !ParserHelpers.IsWhitespaceOrNewLine(this.CurrentCharacter) && !this.AtSymbol())
      {
        ch1 = this.CurrentCharacter;
        this.TakeCurrent();
      }
      if (this.CurrentCharacter == '@')
      {
        char ch2 = this.Peek();
        if (ParserHelpers.IsLetterOrDecimalDigit(ch1) && ParserHelpers.IsLetterOrDecimalDigit(ch2))
        {
          this.TakeCurrent();
          return this.Stay();
        }
      }
      return this.Transition(this.EndSymbol(HtmlSymbolType.Text), new StateMachine<HtmlSymbol>.State(this.Data));
    }

    private HtmlSymbol Symbol()
    {
      char currentCharacter = this.CurrentCharacter;
      this.TakeCurrent();
      switch (currentCharacter)
      {
        case '!':
          return this.EndSymbol(HtmlSymbolType.Bang);
        case '"':
          return this.EndSymbol(HtmlSymbolType.DoubleQuote);
        case '\'':
          return this.EndSymbol(HtmlSymbolType.SingleQuote);
        case '-':
          this.TakeCurrent();
          return this.EndSymbol(HtmlSymbolType.DoubleHyphen);
        case '/':
          return this.EndSymbol(HtmlSymbolType.Solidus);
        case '<':
          return this.EndSymbol(HtmlSymbolType.OpenAngle);
        case '=':
          return this.EndSymbol(HtmlSymbolType.Equals);
        case '>':
          return this.EndSymbol(HtmlSymbolType.CloseAngle);
        case '?':
          return this.EndSymbol(HtmlSymbolType.QuestionMark);
        case '[':
          return this.EndSymbol(HtmlSymbolType.LeftBracket);
        case ']':
          return this.EndSymbol(HtmlSymbolType.RightBracket);
        default:
          return this.EndSymbol(HtmlSymbolType.Unknown);
      }
    }

    private HtmlSymbol Whitespace()
    {
      while (ParserHelpers.IsWhitespace(this.CurrentCharacter))
        this.TakeCurrent();
      return this.EndSymbol(HtmlSymbolType.WhiteSpace);
    }

    private HtmlSymbol Newline()
    {
      int num = this.CurrentCharacter == '\r' ? 1 : 0;
      this.TakeCurrent();
      if (num != 0 && this.CurrentCharacter == '\n')
        this.TakeCurrent();
      return this.EndSymbol(HtmlSymbolType.NewLine);
    }

    private bool AtSymbol()
    {
      if (this.CurrentCharacter == '<' || this.CurrentCharacter == '<' || (this.CurrentCharacter == '!' || this.CurrentCharacter == '/') || (this.CurrentCharacter == '?' || this.CurrentCharacter == '[' || (this.CurrentCharacter == '>' || this.CurrentCharacter == ']')) || (this.CurrentCharacter == '=' || this.CurrentCharacter == '"' || (this.CurrentCharacter == '\'' || this.CurrentCharacter == '@')))
        return true;
      return this.CurrentCharacter == '-' && this.Peek() == '-';
    }
  }
}
